package com.xbdun.web.validatebmp.service;

import java.io.File;
import java.io.FileNotFoundException;
import java.net.URL;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import com.alibaba.fastjson.JSON;
import com.xbdun.common.util.CodeUtil;
import com.xbdun.common.util.CommonUtil;
import com.xbdun.facade.validatebmp.request.GenroScanQrRequest;
import com.xbdun.facade.validatebmp.request.WxUnionCallRequest;
import com.xbdun.facade.validatebmp.response.QrCodeResponse;
import com.xbdun.facade.validatebmp.response.WxUnionCallPcResponse;
import com.xbdun.web.validatebmp.utils.qr.QRCodeUtil;

@Service
public class QrCodeService {
	// 动态生成二维码
	@Autowired
	StringRedisTemplate stringRedisTemplate;
	
	@Value("${xbdun.protocol.validatebmp}")
	private String baseUrl;//当前应用的具体URL地址
	private static final String SPLIT_CHAR = "_XBDUN_";//拆分字符
	// 图片地址
	String url = "";
	@PostConstruct
	public void init() {
		try {
			File icon = new File(ResourceUtils.getFile("classpath:").getAbsolutePath() + "/static/logo.jpg");
			if (icon.exists())
				url = icon.getAbsolutePath();
		} catch (FileNotFoundException e) {
		}
	}

	/**
	 * 生成二维码
	 * 
	 * @param clientNo
	 *            渠道编号
	 * @param userId
	 *            当前用户编号
	 * @param context
	 *            内容
	 * @param hashIcon
	 *            是否中间显示公司LOGO,true:显示,fase:不显示
	 * @param qrSize
	 *            二维码宽高为null默认
	 * @param widthx
	 *            中间图片宽度为null默认
	 * @param heightx
	 *            中间图片高度为null默认
	 * @return
	 */
	public QrCodeResponse encodeByte(GenroScanQrRequest request) throws Exception {
		QrCodeResponse result = new QrCodeResponse();
		byte[] bytex = qrBytes(request);
		// 16进制图片字符串
		result.setImgBytes(CodeUtil.toHexString(bytex));
		return result;
	}
	
	/**
	* @Title: validateInputQr
	* @Description	校验二维码验证
	* @param request
	* @return    设定文件
	* @return boolean    返回类型
	 */
	public boolean validateInputQr(WxUnionCallRequest request){
		String string = stringRedisTemplate.opsForValue().get(request.getData());
		//这里存在该字符,先删除后重新设置值
		if(StringUtils.isNotBlank(string)){
			stringRedisTemplate.delete(request.getData());
			String[] split = string.split(SPLIT_CHAR);
			if(split.length!=2)return false;
			request.setIpAddr(split[1]);//PC端IP地址，用于校验地址防止被串改
			stringRedisTemplate.opsForValue().set(split[0], JSON.toJSONString(request));
			stringRedisTemplate.expire(split[0],3, TimeUnit.MINUTES);
			return true;
		}
		return false;
	}
	
	/**
	* @Title: getQrValue
	* @Description 获取二维码信息
	* @param redisKey
	* @return String    返回类型
	 */
	public WxUnionCallPcResponse getQrValue(String redisKey)throws Exception{
		WxUnionCallPcResponse respon = null;
		String string = stringRedisTemplate.opsForValue().get(redisKey);
		if(StringUtils.isNotBlank(string)){
			stringRedisTemplate.delete(redisKey);
			respon = JSON.parseObject(string,WxUnionCallPcResponse.class);
		}
		return respon;
	}
	/**
	* @Title: printGenroQr
	* @Description: TODO(这里用一句话描述这个方法的作用)
	* @param ipAddr	客户端IP地址
	* @param request		请求对象
	* @param response		response
	* @param httMethod		需要执行方法
	* @throws Exception    设定文件
	* @return void    返回类型
	 */
	public void printGenroQr(String ipAddr,GenroScanQrRequest request,HttpServletResponse response,String httMethod) throws Exception{
		//键
		String settingPwd = null;
		try{
			//判断申请的二维码Value是否已经存在了
			if(stringRedisTemplate.hasKey(request.getScanQrValue())){
				stringRedisTemplate.delete(request.getScanQrValue());
			}
			long stamptime = System.currentTimeMillis();
			String replaceAll = UUID.randomUUID().toString().replaceAll("-", "");
			settingPwd = CommonUtil.settingPwd(request.getScanQrKey()+replaceAll+request.getTimestamp()+request.getScanQrValue()+ipAddr,stamptime+"");
			//设置印象时间
			request.setEffectTime(request.getEffectTime()==0?5:(request.getEffectTime()>148?148:request.getEffectTime()));
			//生成协议内容
			String xbunProtocol = CommonUtil.setProtocol(baseUrl+httMethod,settingPwd);
			
			//设置通用生成二位码数据
			stringRedisTemplate.opsForValue().set(settingPwd,request.getScanQrValue()+SPLIT_CHAR+ipAddr);
			stringRedisTemplate.expire(settingPwd,request.getEffectTime(), TimeUnit.MINUTES);
			//设置协议内容二维码
			request.setScanQrValue(xbunProtocol);
			byte[] bytex = qrBytes(request);
			QRCodeUtil.wirteOut(bytex,response.getOutputStream());	
		}catch(Exception e){
			//删除二维码
			if(null!=settingPwd){
				stringRedisTemplate.delete(settingPwd);
			}
			throw e;
		}
	}
	
	//生成二维码数组
	private byte[] qrBytes(GenroScanQrRequest request) throws Exception{
		byte[] bytex = null;
		if (StringUtils.isBlank(request.getUrl())) {
			bytex = QRCodeUtil.encodeByte(request.getScanQrValue(), "", request.getNeedIoc(), request.getQrSize(),
					request.getWidth(), request.getHeight());
		} else if ("DEFAULT".equalsIgnoreCase(request.getUrl())) {
			bytex = QRCodeUtil.encodeByte(request.getScanQrValue(), url, request.getNeedIoc(), request.getQrSize(),
					request.getWidth(), request.getHeight());
		} else {
			bytex = QRCodeUtil.encodeByte(request.getScanQrValue(), new URL(request.getUrl()), request.getNeedIoc(),
					request.getQrSize(), request.getWidth(), request.getHeight());
		}
		return bytex;
	}
	
	/**
	* @Title: encodeByte
	* @Description: 生成二维码字节码数组
	* @param urlArg		连接
	* @param scnQrValue	二维码值
	* @param needIoc	是否需要ioc
	* @param qrSize		二维码尺寸
	* @param height		高
	* @param width		宽
	* @throws Exception    设定文件
	* @return byte[]    返回类型
	 */
	public  byte[] encodeByte(String urlArg,String scnQrValue,Boolean needIoc,Integer qrSize,Integer height,Integer width)throws Exception{
		byte[] bytex = null;
		if(null==needIoc)needIoc = false;
		if (StringUtils.isBlank(urlArg)) {
			bytex = QRCodeUtil.encodeByte(scnQrValue, "",needIoc,qrSize,width,height);
		} else if ("DEFAULT".equalsIgnoreCase(urlArg)) {
			bytex = QRCodeUtil.encodeByte(scnQrValue, url,needIoc,qrSize,width,height);
		} else {
			bytex = QRCodeUtil.encodeByte(scnQrValue, new URL(urlArg),needIoc,qrSize,width,height);
		}
		return bytex;
	}
}
